using System;
using System.Collections.Generic;
using UnityEngine;

namespace WolfCarol.AvgToolkit.Localization
{
    public interface ILocalizable
    {
        public string key { get; set; }

        public void OnLanguageChanged(string token);
    }

    public abstract class LocalBase : MonoBehaviour, ILocalizable
    {
        [SerializeField] protected string m_key;

        public string key
        {
            get
            {
                return m_key;
            }
            set
            {
                m_key = value;
            }
        }

        public abstract void OnLanguageChanged(string token);
    }

    public abstract class LocalBase<T> : LocalBase where T : Component
    {
        protected T m_component;

        private void Awake()
        {
            m_component = GetComponent<T>();
        }
    }

    public enum LanguageCode
    {
        CN = 0,
        EN = 1,
        JP = 2
    }

    public class LocalizationManager : MonoBehaviour
    {
        [SerializeField] private TextAsset m_translationTable;

        public TextAsset translationTable
        {
            get
            {
                return m_translationTable;
            }
            set
            {
                if (m_translationTable != value)
                {
                    m_translationTable = value;
                    LoadTranslationDictionary();
                }
            }
        }

        [SerializeField] private LanguageCode m_languageCode;

        public LanguageCode languageCode
        {
            get
            {
                return m_languageCode;
            }
            set
            {
                if (m_languageCode != value)
                {
                    m_languageCode = value;
                    OnLanguageChanged();
                }
            }
        }

        public List<LocalBase> localizationList = new();

        private Dictionary<string, string[]> m_translationDictionary = new();

        private void Start()
        {
            LoadTranslationDictionary();
            OnLanguageChanged();
        }

        private void LoadTranslationDictionary()
        {
            if (m_translationTable == null)
            {
                return;
            }

            m_translationDictionary.Clear();
            string[] locals = m_translationTable.text.Split('\n');
            for (int i = 0; i < locals.Length; i++)
            {
                if (string.IsNullOrEmpty(locals[i]) == false)
                {
                    string[] splited = locals[i].Split(',');
                    m_translationDictionary.Add(splited[0], splited[1..]);
                }
            }
        }

        private void OnLanguageChanged()
        {
            if (localizationList == null)
            {
                return;
            }

            foreach (var item in localizationList)
            {
                item.OnLanguageChanged(GetLocalToken(item.key));
            }
        }

        public string GetLocalToken(string key)
        {
            if (m_translationDictionary.ContainsKey(key) == false)
            {
                throw new ArgumentException($"Could not find the key({key}).");
            }

            int index = (int)m_languageCode;

            if (index < 0 || index >= m_translationDictionary[key].Length)
            {
                throw new ArgumentOutOfRangeException($"Could not find the language({m_languageCode}) translation.");
            }

            return m_translationDictionary[key][index];
        }
    }
}
